#include "../include/child_func.h"


int reception(int new_fd)
{
    chdir("./user_space/");

    client_fd = new_fd;
    is_running = 1;

    while (is_running)
    {
        memset(&t_data, 0, sizeof(t_data));
        memset(&r_data, 0, sizeof(r_data));
        ret = recv(client_fd, &t_data, sizeof(t_data), 0);
        if (ret == 0)
        {
            is_running = 0;
        }
        printf("get command: %s\n", t_data.buf);

        if (!strncmp(t_data.buf, "cd", 2))
        {
            exec_cd();
        }
        else if (!strncmp(t_data.buf, "ls", 2))
        {
            exec_ls();
        }
        else if (!strncmp(t_data.buf, "puts", 4))
        {
            exec_puts();
        }
        else if (!strncmp(t_data.buf, "gets", 4))
        {
            exec_gets();
        }
        else if (!strncmp(t_data.buf, "remove", 6))
        {
            exec_remove();
        }
        else if (!strcmp(t_data.buf, "pwd"))
        {
            exec_pwd();
        }
    }
}

int exec_cd()
{
    ret = chdir(t_data.buf + 3);
    if (ret == -1)
    {
        strcpy(r_data.buf, "cd faild");
    }
    else
    {
        getcwd(r_data.buf, 0);
    }

    send(client_fd, &r_data, sizeof(r_data), 0);
}


int exec_ls()
{
    char path[BUFFSIZE] = {0};
    strcpy(path, t_data.buf +3);
    if (!strlen(path))
    {
        strcpy(path, ".");
    }

    DIR *pd = opendir(path);
    if (pd == NULL)
    {
        strcpy(r_data.buf, "No such file or directory");
    } 
    else
    {
        struct dirent* p;
        struct stat buf;

        long int total_size = 0;
        char file_kind;
        char file_name[BUFFSIZE] = {0};
        char tmp[BUFFSIZE] = {0};
        while (p = readdir(pd))
        {
            if (!strcmp(p->d_name, ".") || !strcmp(p->d_name, ".."))
            {
                continue;
            }

            memset(file_name, 0, sizeof(file_name));
            memset(tmp, 0, sizeof(tmp));

            sprintf(file_name, "%s%s%s", path, "/", p->d_name);

            ret = stat(file_name, &buf);
            ERROR_CHECK(ret, -1, "stat");

            if (S_ISDIR(buf.st_mode))
            {
                file_kind = 'd';
            }
            else
            {
                file_kind = '-';
            }

            sprintf(tmp, "%c %-20s %6ld B \n", file_kind, p->d_name, buf.st_size);
            total_size += buf.st_size;

            strcat(r_data.buf, tmp);
        }

        char total_size_str[128] = {0};
        if (total_size > 0) 
        {
            sprintf(total_size_str, "total size: %ldB\n", total_size);
        } 
        else 
        {
            sprintf(total_size_str, "empty folder\n");
        }
        strcat(r_data.buf, total_size_str);
        closedir(pd);
    }

    send(client_fd, &r_data, sizeof(r_data), 0);
}

int exec_puts()
{
    download_file(client_fd);
}

int exec_gets()
{
    struct stat buf;
    ret = stat(t_data.buf + 5, &buf);

    if (S_ISDIR(buf.st_mode) || ret == -1)
    {
        strcpy(r_data.buf, "No such file");
        r_data.data_len = 0;
        send(client_fd, &r_data, sizeof(r_data), 0);
        return -1;
    }
    else
    {
        r_data.data_len = 1;
        send(client_fd, &r_data, sizeof(r_data), 0);

        upload_file(client_fd, t_data.buf + 5);
        
        return 0;
    }
}

int exec_remove()
{
    char rm_str[BUFFSIZE] = {0};
    sprintf(rm_str, "rm -rf %s", t_data.buf + 7);

    ret = system(rm_str);
    if (ret == 0)
    {
        strcpy(r_data.buf, "remove success!");
    } 
    else
    {
        strcpy(r_data.buf, "remove failed! No such file or directory");
    }
    
    send(client_fd, &r_data, sizeof(r_data), 0);

    return 0;
}

int exec_pwd()
{
    getcwd(r_data.buf, 255);
    
    send(client_fd, &r_data, sizeof(r_data), 0);

    return 0;
}